home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1993 April
/
CICA MS Windows - April 1993.iso
/
unzipped
/
misc
/
lissajou
/
lissajou.c
< prev
next >
Wrap
Text File
|
1991-05-07
|
13KB
|
407 lines
/* the LISSAJOU application by K.Steffens (STEFFENS@DMSWWU5P.BITNET)
this program is donated to the public domain as long as it is
distributed together with the sources and the executable */
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "lissajou.h"
/* the function prototypes */
int PASCAL WinMain(HANDLE,HANDLE,LPSTR,int);
BOOL InitApplication(HANDLE);
long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL About(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL SetParams(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL TurnLeft(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL TurnRight(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL StatusBox(HWND, unsigned, WORD, LONG);
void LissajousPlot(HDC, WORD, WORD);
HANDLE hInst, hAccTable;
float x_fact, y_fact, d_phi, r_phi;
int n_steps,r_speed, iDirection;
WORD idTimer;
BOOL bAutoRotate, bStatusBox;
HMENU hMenu;
HWND hStatusBox;
/* Here comes the Main Window function - it is similar to the
Generic Application Main function from the SDK handbooks */
int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
MSG msg;
HWND hWnd;
hInst = hInstance;
/* if no previous instances are there then initialization required */
if (!hPrevInstance)
if (!InitApplication(hInstance))
return (FALSE); /* Error exit*/
/* Initialize some global variables */
x_fact = 1.0;
y_fact = 1.0;
d_phi = 0.0;
n_steps= 100;
r_phi = 3.0;
bAutoRotate = FALSE;
r_speed = 500;
iDirection = 1;
/* we need a Menu Handle cause we want to manipulate the
pulldown entries (checkmarks) */
hMenu = LoadMenu(hInst,"LissajousMenu");
hWnd= CreateWindow("LissajousWClass","Karsten's Lissajou 1.0"
,WS_OVERLAPPEDWINDOW
,CW_USEDEFAULT,CW_USEDEFAULT,220,229
,(HWND) NULL
,hMenu
,hInstance
, NULL);
if (!hWnd)
return(FALSE); /* window could not be created */
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
/* dispatch the messages
somewhat extended cause we use an AcceleratorTable */
while (GetMessage(&msg,NULL,NULL,NULL))
{
if (!TranslateAccelerator(hWnd, hAccTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (msg.wParam);
}
BOOL InitApplication(hInstance)
HANDLE hInstance;
{
WNDCLASS wc;
/* the windowclass.style should be defined such that Windows automatically
sends a WM_PAINT on resizing the window */
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, "LissajousIcon");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "LissajousMenu";
wc.lpszClassName= "LissajousWClass";
return (RegisterClass(&wc));
}
long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
FARPROC lpProcAbout
,lpProcSetParams
,lpProcStatusBox;
PAINTSTRUCT ps;
HDC hDC;
switch (message)
{
case WM_CREATE:
hAccTable = LoadAccelerators(hInst,"LissajousMenu");
break;
case WM_INITDIALOG:
return (TRUE);
break;
/* if we select the Autorotate feature then every timer click the
Lissajou-Application sends a message containing the order to
turn left or right: this is similar to a computer hitting its own
keys... */
case WM_TIMER:
if (iDirection==1)
SendMessage(hWnd, (WORD) WM_COMMAND, (WORD) IDM_RIGHTTURN, (LONG) NULL);
else
SendMessage(hWnd, (WORD) WM_COMMAND, (WORD) IDM_LEFTTURN, (LONG) NULL);
break;
case WM_COMMAND:
switch (wParam)
{
case IDM_ABOUT:
lpProcAbout = MakeProcInstance(About,hInst);
DialogBox(hInst,"AboutBox",hWnd,lpProcAbout);
FreeProcInstance(lpProcAbout);
break;
case IDM_SETPAR:
lpProcSetParams = MakeProcInstance(SetParams,hInst);
DialogBox(hInst,"SetParams",hWnd,lpProcSetParams);
FreeProcInstance(lpProcSetParams);
InvalidateRect(hWnd, NULL,TRUE);
if (bStatusBox) InvalidateRect(hStatusBox,NULL,FALSE);
break;
case IDM_LEFTTURN:
d_phi -= r_phi;
if (d_phi<0.0) d_phi += 360.0;
iDirection = -1;
InvalidateRect(hWnd, NULL, TRUE);
if (bStatusBox) InvalidateRect(hStatusBox,NULL,FALSE);
break;
case IDM_RIGHTTURN:
d_phi += r_phi;
if (d_phi>360.0) d_phi -= 360.0;
iDirection = 1;
InvalidateRect(hWnd, NULL, TRUE);
if (bStatusBox) InvalidateRect(hStatusBox,NULL,FALSE);
break;
/* autorotate feature keeps track of its status in bAutoRotate. If it is
switched on it starts a timer, when it is switched off, it kills that
timer */
case IDM_AUTOROTATE:
if (bAutoRotate)
{
bAutoRotate = FALSE;
CheckMenuItem(hMenu, IDM_AUTOROTATE, MF_UNCHECKED);
KillTimer(hWnd, 1);
}
else
{
bAutoRotate = TRUE;
CheckMenuItem(hMenu, IDM_AUTOROTATE, MF_CHECKED);
idTimer = SetTimer(hWnd, 1, r_speed, (FARPROC) NULL);
}
break;
/* here we make use of a modeless dialog box: this is because we want to
have the status box displayed and want to continue work somewhere else */
case IDM_STATUSBOX:
if (bStatusBox)
{
bStatusBox = FALSE;
CheckMenuItem(hMenu, IDM_STATUSBOX, MF_UNCHECKED);
ShowWindow(hStatusBox,SW_HIDE);
DestroyWindow(hStatusBox);
FreeProcInstance(lpProcStatusBox);
}
else
{
bStatusBox = TRUE;
CheckMenuItem(hMenu, IDM_STATUSBOX, MF_CHECKED);
lpProcStatusBox = MakeProcInstance(StatusBox,hInst);
hStatusBox=CreateDialog(hInst,"StatusBox",hWnd,lpProcStatusBox);
}
break;
default:
return (DefWindowProc(hWnd,message,wParam,lParam));
}
break;
case WM_PAINT:
{
WORD wViewX, wViewY;
RECT rcClient;
hDC = BeginPaint (hWnd,&ps);
GetClientRect(hWnd,&rcClient);
wViewX = rcClient.right - rcClient.left - 1;
wViewY = rcClient.bottom - rcClient.top - 1;
SetViewportExt(hDC,wViewX,wViewY);
LissajousPlot(hDC, wViewX, wViewY);
EndPaint (hWnd,&ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd,message,wParam,lParam));
}
return(NULL);
}
BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
switch (message)
{
case WM_INITDIALOG:
return(TRUE);
case WM_COMMAND:
if (wParam == IDOK || wParam == IDCANCEL)
{
EndDialog(hDlg,TRUE);
return(TRUE);
}
break;
}
return(FALSE);
}
BOOL FAR PASCAL SetParams(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
char szTmp[127];
switch (message)
{
case WM_INITDIALOG:
sprintf(szTmp,"%9.1f",x_fact);
SetDlgItemText(hDlg,IDM_XFACTOR,szTmp);
sprintf(szTmp,"%9.1f",y_fact);
SetDlgItemText(hDlg,IDM_YFACTOR,szTmp);
sprintf(szTmp,"%9.1f",d_phi);
SetDlgItemText(hDlg,IDM_PHISHIFT,szTmp);
SetDlgItemInt(hDlg,IDM_NSTEPS,n_steps,TRUE);
sprintf(szTmp,"%9.1f",r_phi);
SetDlgItemText(hDlg,IDM_PHIROTATE,szTmp);
SetDlgItemInt(hDlg,IDM_ROTATESPEED,r_speed,TRUE);
return(TRUE);
case WM_COMMAND:
switch (wParam)
{
case IDOK:
GetDlgItemText(hDlg,IDM_XFACTOR,szTmp,127);
sscanf(szTmp,"%f",&x_fact);
if (x_fact<0.0) x_fact = 1.0;
GetDlgItemText(hDlg,IDM_YFACTOR,szTmp,127);
sscanf(szTmp,"%f",&y_fact);
if (y_fact<0.0) y_fact = 1.0;
GetDlgItemText(hDlg,IDM_PHISHIFT,szTmp,127);
sscanf(szTmp,"%f",&d_phi);
if (d_phi<0.0) d_phi = 0.0;
while (d_phi>360.0) d_phi -= 360.0;
GetDlgItemText(hDlg,IDM_NSTEPS,szTmp,127);
sscanf(szTmp,"%d",&n_steps);
if (n_steps<3) n_steps = 3;
GetDlgItemText(hDlg,IDM_PHIROTATE,szTmp,127);
sscanf(szTmp,"%f",&r_phi);
GetDlgItemText(hDlg,IDM_ROTATESPEED,szTmp,127);
sscanf(szTmp,"%d",&r_speed);
if (r_speed < 100) r_speed = 100;
EndDialog(hDlg,TRUE);
return(TRUE);
break;
case IDCANCEL:
EndDialog(hDlg,TRUE);
return(TRUE);
break;
}
break;
}
return(FALSE);
}
void LissajousPlot(hDC, x_win, y_win)
HDC hDC;
WORD x_win,y_win;
{
float phi,phi_step,radians;
int ijk, x, y;
phi_step = 360.0 / (float) n_steps;
radians = 3.1415926 / 180.0;
x= x_win/2;
y= y_win/2 + (int) ((y_win/2.2) * cos(y_fact*d_phi*radians));
MoveTo(hDC,x,y);
for (ijk=0;ijk<=n_steps;ijk++)
{
phi = ijk*phi_step * radians;
x = x_win/2 + (int)((x_win/2.2) * sin(x_fact*phi));
y = y_win/2 + (int)((y_win/2.2) * cos(y_fact*(phi+d_phi*radians)));
LineTo(hDC,x,y);
}
}
BOOL FAR PASCAL StatusBox(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
char szTmp[127];
PAINTSTRUCT ps;
HDC hDC;
switch (message)
{
case WM_PAINT:
hDC = BeginPaint (hDlg,&ps);
sprintf(szTmp,"%9.1f",x_fact);
SetDlgItemText(hDlg,IDM_STATX,szTmp);
sprintf(szTmp,"%9.1f",y_fact);
SetDlgItemText(hDlg,IDM_STATY,szTmp);
sprintf(szTmp,"%9.1f",d_phi);
SetDlgItemText(hDlg,IDM_STATP,szTmp);
sprintf(szTmp,"%d",n_steps);
SetDlgItemText(hDlg,IDM_STATNS,szTmp);
sprintf(szTmp,"%9.1f",r_phi);
SetDlgItemText(hDlg,IDM_STATR,szTmp);
sprintf(szTmp,"%d",r_speed);
SetDlgItemText(hDlg,IDM_STATRS,szTmp);
EndPaint (hDlg,&ps);
break;
case WM_INITDIALOG:
sprintf(szTmp,"%9.1f",x_fact);
SetDlgItemText(hDlg,IDM_STATX,szTmp);
sprintf(szTmp,"%9.1f",y_fact);
SetDlgItemText(hDlg,IDM_STATY,szTmp);
sprintf(szTmp,"%9.1f",d_phi);
SetDlgItemText(hDlg,IDM_STATP,szTmp);
sprintf(szTmp,"%d",n_steps);
SetDlgItemText(hDlg,IDM_STATNS,szTmp);
sprintf(szTmp,"%9.1f",r_phi);
SetDlgItemText(hDlg,IDM_STATR,szTmp);
sprintf(szTmp,"%d",r_speed);
SetDlgItemText(hDlg,IDM_STATRS,szTmp);
ShowWindow(hDlg,SW_SHOW);
return(TRUE);
break;
}
return(FALSE);
}